package com.example.appointment.util;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Environment;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class CmnObjectFuncs {
    /**
     * 把raw的文件存储到SD卡中
     *
     * @param name
     * @throws Throwable
     */
    public static void saveToSDCard(String name, Context context, int firleid) throws Throwable {
        InputStream inStream = context.getResources().openRawResource(firleid);
        File file = new File(Environment.getExternalStorageDirectory(), name);
        FileOutputStream fileOutputStream = new FileOutputStream(file);//存入SDCard
        byte[] buffer = new byte[10];
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, len);
        }
        byte[] bs = outStream.toByteArray();
        fileOutputStream.write(bs);
        outStream.close();
        inStream.close();
        fileOutputStream.flush();
        fileOutputStream.close();
    }

    public static int getAndroidSDKVersion() {
        int version = 0;
        try {
            version = Integer.valueOf(android.os.Build.VERSION.SDK);
        } catch (NumberFormatException e) {
            //Log.e(e.toString());
        }
        return version;
    }

    /**
     * 根据指定的图像路径和大小来获取缩略图
     * 此方法有两点好处：
     * 1. 使用较小的内存空间，第一次获取的bitmap实际上为null，只是为了读取宽度和高度，
     * 第二次读取的bitmap是根据比例压缩过的图像，第三次读取的bitmap是所要的缩略图。
     * 2. 缩略图对于原图像来讲没有拉伸，这里使用了2.2版本的新工具ThumbnailUtils，使
     * 用这个工具生成的图像不会被拉伸。
     *
     * @param imagePath 图像的路径
     * @param width     指定输出图像的宽度
     * @param height    指定输出图像的高度
     * @return 生成的缩略图
     */
    public static Bitmap getImageThumbnail(String imagePath, int width, int height) {
        Bitmap bitmap = null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        // 获取这个图片的宽和高，注意此处的bitmap为null
        bitmap = BitmapFactory.decodeFile(imagePath, options);
        options.inJustDecodeBounds = false; // 设为 false
        // 计算缩放比
        int h = options.outHeight;
        int w = options.outWidth;
        int beWidth = w / width;
        int beHeight = h / height;
        int be = 1;
        if (beWidth < beHeight) {
            be = beWidth;
        } else {
            be = beHeight;
        }
        if (be <= 0) {
            be = 1;
        }
        options.inSampleSize = be;
        // 重新读入图片，读取缩放后的bitmap，注意这次要把options.inJustDecodeBounds 设为 false
        bitmap = BitmapFactory.decodeFile(imagePath, options);
        // 利用ThumbnailUtils来创建缩略图，这里要指定要缩放哪个Bitmap对象
        bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
                ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
        return bitmap;
    }

    /**
     * 获取视频的缩略图
     * 先通过ThumbnailUtils来创建一个视频的缩略图，然后再利用ThumbnailUtils来生成指定大小的缩略图。
     * 如果想要的缩略图的宽和高都小于MICRO_KIND，则类型要使用MICRO_KIND作为kind的值，这样会节省内存。
     *
     * @param videoPath 视频的路径
     * @param width     指定输出视频缩略图的宽度
     * @param height    指定输出视频缩略图的高度度
     * @param kind      参照MediaStore.Images.Thumbnails类中的常量MINI_KIND和MICRO_KIND。
     *                  其中，MINI_KIND: 512 x 384，MICRO_KIND: 96 x 96
     * @return 指定大小的视频缩略图
     */
    public static Bitmap getVideoThumbnail(String videoPath, int width, int height,
                                           int kind) {
        Bitmap bitmap = null;
        // 获取视频的缩略图
        bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, kind);
        System.out.println("w" + bitmap.getWidth());
        System.out.println("h" + bitmap.getHeight());
        bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
                ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
        return bitmap;
    }


    public static String getInnerSDCardPath() {
        return Environment.getExternalStorageDirectory().getPath();

    }

    public static String getExtSDCardPath() {

        String ret = "";

        ArrayList<String> lResult = getExtSDCardPathArrayList();
        if (lResult.size() > 0)
            ret = lResult.get(0);

        return ret;
    }


    private static ArrayList<String> getExtSDCardPathArrayList() {
        ArrayList<String> lResult = new ArrayList<String>();
        try {
            Runtime rt = Runtime.getRuntime();
            Process proc = rt.exec("mount");
            InputStream is = proc.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String line;
            while ((line = br.readLine()) != null) {
                if (line.contains("extSdCard")) {
                    String[] arr = line.split(" ");
                    String path = arr[1];
                    if (path.contains("."))
                        continue;
                    File file = new File(path);
                    if (file.isDirectory()) {
                        lResult.add(path);
                    }
                }
            }
            isr.close();
        } catch (Exception e) {
        }
        return lResult;
    }


    public static Point getCenterPoint(Point a, int la, Point b, int lb, Point c, int lc) {


        if (la < 100 || lb < 100 || lc < 100) {

            int minL = 101;
            minL = Math.min(la, lb);
            minL = Math.min(minL, lc);

            if (minL == la)
                return a;
            else if (minL == lb)
                return b;
            else if (minL == lc)
                return c;

        }


        int distanceAB = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
        if (distanceAB > (la + lb) * (la + lb))
            return null;

        int distanceAC = (a.x - c.x) * (a.x - c.x) + (a.y - c.y) * (a.y - c.y);
        if (distanceAC > (la + lc) * (la + lc))
            return null;

        int distanceBC = (b.x - c.x) * (b.x - c.x) + (b.y - c.y) * (b.y - c.y);
        if (distanceBC > (lb + lc) * (lb + lc))
            return null;

//        int count=100;
//        double angle=2*Math.PI/count;
//
//        ArrayList<Point> aPointArrayList=new ArrayList<>();
//        ArrayList<Point> bPointArrayList=new ArrayList<>();
//        ArrayList<Point> cPointArrayList=new ArrayList<>();
//
//
//        for(int i=0;i<count;i++)
//        {
//            int lx= (int) (Math.cos(angle*i)*la);
//            int ly= (int) (Math.sin(angle * i)*la);
//            aPointArrayList.add(new Point(a.x+lx,a.y+ly));
//        }
//
//        for(int i=0;i<count;i++)
//        {
//            int lx= (int) (Math.cos(angle*i)*lb);
//            int ly= (int) (Math.sin(angle * i)*lb);
//            bPointArrayList.add(new Point(b.x+lx,b.y+ly));
//        }
//        for(int i=0;i<count;i++)
//        {
//            int lx= (int) (Math.cos(angle*i)*lc);
//            int ly= (int) (Math.sin(angle * i)*lc);
//            cPointArrayList.add(new Point(c.x+lx,c.y+ly));
//        }


        ArrayList<Point> abPoints = getIntersectPoints(a, la, b, lb);
        ArrayList<Point> acPoints = getIntersectPoints(a, la, c, lc);
        ArrayList<Point> bcPoints = getIntersectPoints(b, lb, c, lc);

//        ArrayList<Point> acPoints=getIntersectPoints(aPointArrayList,cPointArrayList);
//        ArrayList<Point> bcPoints=getIntersectPoints(bPointArrayList,cPointArrayList);

        int pointx = abPoints.get(0).x / 6 + abPoints.get(1).x / 6 + acPoints.get(0).x / 6 + acPoints.get(1).x / 6 +
                bcPoints.get(0).x / 6 + bcPoints.get(1).x / 6;

        int pointy = abPoints.get(0).y / 6 + abPoints.get(1).y / 6 + acPoints.get(0).y / 6 + acPoints.get(1).y / 6 +
                bcPoints.get(0).y / 6 + bcPoints.get(1).y / 6;

        return new Point(pointx, pointy);


    }

//    public static ArrayList<Point> getIntersectPoints(ArrayList<Point> cicleArray1,ArrayList<Point> cicleArray2)
//    {
//        Point point1=null;
//        Point point2=null;
//        for(int i=0;i<cicleArray1.size()-1;i++)
//        {
//            for(int j=0;j<cicleArray2.size()-1;j++)
//            {
//                Point aTempPoint1=cicleArray1.get(i);
//                Point aTempPoint2=cicleArray1.get(i+1);
//                Point bTempPoint1=cicleArray2.get(j);
//                Point bTempPoint2=cicleArray2.get(j+1);
//                if(isLineIntersected(aTempPoint1,aTempPoint2,bTempPoint1,bTempPoint2))
//                {
//                    if (point1 == null)
//                        point1 = aTempPoint1;
//                    else
//                        point2 = aTempPoint1;
//
////                        if (point2 != null)
////                            break;
//
//                }
//
//
//
//            }
//
////            if(point2!=null)
////                break;
//
//        }
//
//        ArrayList<Point> points=new ArrayList<>();
//        points.add(point1);
//        points.add(point2);
//
//        return points;
//
//
//    }

    public static ArrayList<Point> getIntersectPoints(Point a, int la, Point b, int lb) {

        int count = 100;
        double angle = 2 * Math.PI / count;

        ArrayList<Point> aPointArrayList = new ArrayList<Point>();
        ArrayList<Point> bPointArrayList = new ArrayList<Point>();


        for (int i = 0; i < count; i++) {
            int lx = (int) (Math.cos(angle * i) * la);
            int ly = (int) (Math.sin(angle * i) * la);
            aPointArrayList.add(new Point(a.x + lx, a.y + ly));
        }

        for (int i = 0; i < count; i++) {
            int lx = (int) (Math.cos(angle * i) * lb);
            int ly = (int) (Math.sin(angle * i) * lb);
            bPointArrayList.add(new Point(b.x + lx, b.y + ly));
        }

        int delta = Math.min((int) (Math.sin(angle) * la), (int) (Math.sin(angle) * lb));


        Point point_min1 = null;
        Point point_min2 = null;
        int distance_min1 = -1;
        int distance_min2 = -1;
        //int distance_prev=-1;

//        Point point1=null;
//        Point point2=null;
        for (int i = 0; i < aPointArrayList.size(); i++) {
            for (int j = 0; j < bPointArrayList.size(); j++) {
                Point aTempPoint1 = aPointArrayList.get(i);
                Point bTempPoint1 = bPointArrayList.get(j);

                int absX = Math.abs(aTempPoint1.x - bTempPoint1.x);
                int absY = Math.abs(aTempPoint1.y - bTempPoint1.y);

                int tempDistance = absX * absX + absY * absY;

                if (distance_min1 == -1) {
                    distance_min1 = tempDistance;
                    point_min1 = aTempPoint1;

                    distance_min2 = tempDistance;
                    point_min2 = aTempPoint1;
                }


                if (tempDistance < distance_min1) {

                    final int x = point_min1.x;
                    final int y = point_min1.y;

                    if ((point_min1.x == aTempPoint1.x) &&
                            (point_min1.y == aTempPoint1.y)) {
                        int k = 0;
                        k++;
                        continue;
                    }

                    distance_min2 = distance_min1;
                    point_min2 = new Point(x, y);

                    distance_min1 = tempDistance;
                    point_min1 = new Point(aTempPoint1.x, aTempPoint1.y);

                    int k = 0;
                    k++;


                } else if (tempDistance < distance_min2) {

                    if (tempDistance > distance_min1) {
                        distance_min2 = tempDistance;
                        point_min2 = new Point(aTempPoint1.x, aTempPoint1.y);

                        int k = 0;
                        k++;
                    } else {
                        int k = 0;
                        k++;

                    }

                }

            }

//            if(point2!=null)
//                break;

        }

        ArrayList<Point> points = new ArrayList<Point>();
        points.add(point_min1);
        points.add(point_min2);

        return points;


    }

    private static boolean isLineIntersected(Point a, Point b, Point c, Point d) {
        int deltaX1 = b.x - a.x;
        int deltaY1 = b.y - a.y;
        int deltaX2 = d.x - c.x;
        int deltaY2 = d.y - c.y;

        if (deltaX1 == 0) {
            int i = 0;
            i++;
            return false;
        }

        if (deltaX2 * deltaY1 - deltaX1 * deltaY2 == 0) {

            int i = 0;
            i++;

            return false;

        }

        Point point = new Point();
        point.x = (deltaX2 * (a.x * deltaY1 - a.y * deltaX1) - deltaX1 * (c.x * deltaY2 - c.y * deltaX2)) / (deltaX2 * deltaY1 - deltaX1 * deltaY2);
        //point.x= (point.y*(b.x-a.x)+a.x*(b.y-a.y)-a.y*(b.x-a.x))/(b.y-a.y);

        point.y = (point.x * deltaY1 + a.y * deltaX1 - a.x * deltaY1) / deltaX1;

        if (point.x < Math.max(a.x, b.x) && point.x > Math.min(a.x, b.x) &&
                point.y < Math.max(a.y, b.y) && point.y > Math.min(a.y, b.y)) {
            return true;
        }

        return false;


    }
//    private static boolean isLineIntersected(Point a, Point b, Point c, Point d)
//    {
//        //判断异常
//        if (Math.abs(b.x - a.y) + Math.abs(b.x - a.x) + Math.abs(d.y - c.y) + Math.abs(d.x - c.x) == 0)
//        {
//            if (c.x - a.x == 0)
//            {
//            }
//            else
//            {
//                //  Debug.Print("AB是一个点，CD是一个点，且AC不同！");
//            }
//            return false;
//        }
//
//        if (Math.abs(b.y - a.y) + Math.abs(b.x - a.x) == 0)
//        {
//            if ((a.x - d.x) * (c.y - d.y) - (a.y - d.y) * (c.x - d.x) == 0)
//            {
//                // Debug.Print ("A、B是一个点，且在CD线段上！");
//            }
//            else
//            {
//                // Debug.Print ("A、B是一个点，且不在CD线段上！");
//            }
//            return false;
//        }
//
//        if (Math.abs(d.y - c.y) + Math.abs(d.x - c.x) == 0)
//        {
//            if ((d.x - b.x) * (a.y - b.y) - (d.y - b.y) * (a.x - b.x) == 0)
//            {
//                //Debug.Print ("C、D是一个点，且在AB线段上！");
//            }
//            else
//            {
//                // Debug.Print ("C、D是一个点，且不在AB线段上！");
//            }
//        }
//
//
//        if ((b.y - a.y) * (c.x - d.x) - (b.x - a.x) * (c.y - d.y) == 0)
//        {
//            // Debug.Print ("线段平行，无交点！");
//            return false;
//        }
//        Point point=new Point();
//
//        point.x = ((b.x - a.x) * (c.x - d.x) * (c.y - a.y) - c.x * (b.x - a.x) * (c.y - d.y) + a.x * (b.y - a.y) * (c.x - d.x)) / ((b.y - a.y) * (c.x - d.x) - (b.x - a.x) * (c.y - d.y));
//        point.y = ((b.y - a.y) * (c.y - d.y) * (c.x - a.x) - c.y * (b.y - a.y) * (c.x - d.x) + a.y * (b.x - a.x) * (c.y - d.y)) / ((b.x - a.x) * (c.y - d.y) - (b.y - a.y) * (c.x - d.x));
//
//
//        if ((point.x - a.x) * (point.x - b.x) <= 0 && (point.x - c.x) * (point.x - d.x) <= 0 && (point.y - a.y) * (point.y - b.y) <= 0 && (point.y - c.y) * (point.y - d.y) <= 0)
//        {
//            //Debug.Print ("线段相交于点(" + intersection.x + "," + intersection.y + ")！");
//            return true; //‘相交
//        }
//        else
//        {
//            //Debug.Print ("线段相交于虚交点(" + intersection.x + "," + intersection.y + ")！");
//            return false; //‘相交但不在线段上
//        }
//
//    }

    //删除文件夹和文件夹里面的文件
    public static void deleteDir(String path) {
        File dir = new File(path);
        if (dir == null || !dir.exists() || !dir.isDirectory())
            return;

        for (File file : dir.listFiles()) {
            if (file.isFile())
                file.delete(); // 删除所有文件
            else if (file.isDirectory())
                deleteDir(file.getPath()); // 递规的方式删除文件夹
        }
        dir.delete();// 删除目录本身
    }

    //判断字符串是否在数组中
    public static boolean isArrayListContainsString(ArrayList<String> arrayList, String value) {
        boolean ret = false;

        for (int i = 0; i < arrayList.size(); i++) {
            if (arrayList.get(i).equals(value)) {
                ret = true;
                break;

            }

        }

        return ret;

    }

    //从数组中移除字符串
    public static void removeStringFromArrayList(ArrayList<String> arrayList, String value) {

        for (int i = 0; i < arrayList.size(); i++) {
            if (arrayList.get(i).equals(value)) {
                arrayList.remove(i);
                break;

            }

        }


    }

    /**
     * 打开文件
     *
     * @param file
     */
    public static void openFile(Context context, File file) {

        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(Intent.ACTION_VIEW);
        String type = getMIMEType(file);
        intent.setDataAndType(Uri.fromFile(file), type);
        context.startActivity(intent);

    }

    /**
     * 根据文件后缀名获得对应的MIME类型。
     *
     * @param file
     */
    public static String getMIMEType(File file) {

        String type = "*/*";
        String fName = file.getName();
        int dotIndex = fName.lastIndexOf(".");
        if (dotIndex < 0) {
            return type;
        }
        String end = fName.substring(dotIndex, fName.length()).toLowerCase();
        if (end == "") return type;
        for (int i = 0; i < CmnObjectDefines.Const_Mime_MapTable.length; i++) {
            if (end.equals(CmnObjectDefines.Const_Mime_MapTable[i][0]))
                type = CmnObjectDefines.Const_Mime_MapTable[i][1];
        }
        return type;
    }


    public static void openAppByPackageName(Context context, String packageName) {
        PackageManager packageManager = context.getPackageManager();
        PackageInfo pi = null;

        try {

            pi = packageManager.getPackageInfo(packageName, 0);
        } catch (PackageManager.NameNotFoundException e) {

        }

        if (pi == null) {
            Toast.makeText(context, "应用程序未安装！", Toast.LENGTH_SHORT).show();
            return;

        }


        Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
        resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        resolveIntent.setPackage(pi.packageName);

        List<ResolveInfo> apps = packageManager.queryIntentActivities(resolveIntent, 0);

        ResolveInfo ri = apps.iterator().next();
        if (ri != null) {
            String className = ri.activityInfo.name;

            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_LAUNCHER);

            ComponentName cn = new ComponentName(packageName, className);

            intent.setComponent(cn);
            context.startActivity(intent);
        }
    }

}
